#include "freertos/FreeRTOS.h"
#include "ServoClock.h"
#include "assets/lang_config.h"
#include "board.h"
#include "display.h"
#include "string.h"
#include "application.h"
#include "mcp_server.h"

#define TAG "ServoClockManager"

#define SERVO_CLOCK_ADDR_0X40      0x40        /*!< I2C address  */
#define SERVO_CLOCK_ADDR_0X41      0x41        /*!< I2C address  */

#define ANGLE_90  90
#define ANGLE_180  180
// 将数组转为字节串
// 定义数字显示编码
uint8_t display_digits[10][7] = {
    {1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 0, 0, 0, 0},
    {1, 1, 0, 1, 1, 0, 1},
    {1, 1, 1, 1, 0, 0, 1},
    {0, 1, 1, 0, 0, 1, 1},
    {1, 0, 1, 1, 0, 1, 1},
    {1, 0, 1, 1, 1, 1, 1},
    {1, 1, 1, 0, 0, 0, 0},
    {1, 1, 1, 1, 1, 1, 1},
    {1, 1, 1, 1, 0, 1, 1}
};

// 将数组转为字节串
// 定义笑脸显示编码
uint8_t display_digits_smile[4][7] = {
    {0, 0, 0, 0, 0, 0, 0},
    {1, 1, 0, 1, 0, 1, 1},
    {1, 1, 0, 1, 0, 1, 1},
    {0, 0, 0, 0, 0, 0, 0}
};

// 将数组转为字节串
// 定义勿扰模式显示编码DND
uint8_t display_digits_dnd[4][7] = {
    {0, 0, 0, 0, 0, 0, 1},
    {0, 0, 0, 0, 0, 0, 1},
    {0, 0, 0, 0, 0, 0, 1},
    {0, 0, 0, 0, 0, 0, 1}
};

// 将数组转为字节串
// 定义温度单位显示编码℃
uint8_t display_digits_degree[4][7] = {
    {0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 0},
    {1, 1, 0, 0, 0, 1, 1},
    {1, 0, 0, 1, 1, 1, 0}
};

// 将数组转为字节串
// 定义%
uint8_t display_digits_persent[4][7] = {
    {0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 0},
    {1, 1, 0, 0, 0, 1, 1},
    {0, 0, 1, 1, 1, 0, 1}
};

ServoClockManager::ServoClockManager()
: m_dispmode(0)
, m_dispYearFlg(false)
, m_dispDateFlg(false)
, m_dispEmoteFlg(false)
, m_dispTimeFlg(false)
, m_CountdownTotalSeconds(0)
{
    m_sDonotDisturbTimePeriodStart.tm_hour = 22;
    m_sDonotDisturbTimePeriodStart.tm_min = 0;
    m_sDonotDisturbTimePeriodEnd.tm_hour = 6;
    m_sDonotDisturbTimePeriodEnd.tm_min =0;

    memset(m_motor_ctrl_board_1, 0, sizeof(m_motor_ctrl_board_1));
    memset(m_motor_ctrl_board_2, 0, sizeof(m_motor_ctrl_board_2));

    memset(m_motor_ctrl_board_1_old, 0, sizeof(m_motor_ctrl_board_1_old));
    memset(m_motor_ctrl_board_2_old, 0, sizeof(m_motor_ctrl_board_2_old));


    ESP_LOGI(TAG, "ServoClockManager init");
    // 创建定时器
    esp_timer_create_args_t timer_args = {
        .callback = [](void* arg) {
            auto self = static_cast<ServoClockManager*>(arg);
            self->OnServoClockTimer();
        },
        .arg = this,
        .dispatch_method = ESP_TIMER_TASK,
        .name = "ServoClock_timer",
        .skip_unhandled_events = true,
    };
    ESP_ERROR_CHECK(esp_timer_create(&timer_args, &clock_timer_handle_));
    ESP_ERROR_CHECK(esp_timer_start_periodic(clock_timer_handle_, 1000000));
    ESP_LOGI(TAG, "创建定时器结束");

    auto& mcp_server = McpServer::GetInstance();
    // 定义设备的属性
    mcp_server.AddTool("self.servoclock.DisplayMode", "机械时钟显示模式: 0:显示时间;1:显示年份;2:显示日期;3:显示秒针/分秒;4:显示笑脸;5:显示倒计时;6:显示计算结果", PropertyList(), [this](const PropertyList&) -> ReturnValue {
        ESP_LOGI(TAG, "get disp status %d", GetDisplayMode());
        return GetDisplayMode();
    });

    mcp_server.AddTool("self.servoclock.CountdownFlg", "机械时钟倒计时结束标志位[true:倒计时结束]", PropertyList(), [this](const PropertyList&) -> ReturnValue {
        ESP_LOGI(TAG, "get countdown flag %d", GetDisplayCountdownFlag());
        return GetDisplayCountdownFlag();
    });


    // 定义设备可以被远程执行的指令
    mcp_server.AddTool("self.servoclock.SetDisplayMode", "设置机械时钟显示模式:0:显示时间;1:显示年份;2:显示日期;3:显示秒针/分秒;4:显示笑脸;7:显示当前温度;8:显示当前湿度", PropertyList({
        Property("mode", kPropertyTypeInteger, 0, 10)
    }), [this](const PropertyList& properties) -> ReturnValue {
        int data = properties["mode"].value<int>();
        ESP_LOGI(TAG, "SetDisplayMode %d", data);
        SetDisplayMode(data);
        return true;
    });

    mcp_server.AddTool("self.servoclock.setcountdowntime", "设定机械时钟倒计时时间,并显示到机械时钟上,minute为分钟,second为秒", PropertyList({
        Property("minute", kPropertyTypeInteger, 0, 59),
        Property("second", kPropertyTypeInteger, 0, 59)
    }), [this](const PropertyList& properties) -> ReturnValue {
        int minute = properties["minute"].value<int>();
        int second = properties["second"].value<int>();
        ESP_LOGI(TAG, "SetCountDownTime %d %d", minute, second);
        SetCountDownTime(minute, second);
        // 5:显示倒计时
        SetDisplayMode(5);
        return true;
    });

    mcp_server.AddTool("self.servoclock.setCalculationResult", "设定加减乘除四则运算的结果,结果限定在4位数,即0到9999之间的整数", PropertyList({
        Property("CalculationResult", kPropertyTypeInteger, 0, 9999)
    }), [this](const PropertyList& properties) -> ReturnValue {
        int data = properties["CalculationResult"].value<int>();
        ESP_LOGI(TAG, "SetCalculationResult %d", data);
        SetCalculationResult(data);
        // 5:显示算数结果
        SetDisplayMode(6);
        return true;
    });

    mcp_server.AddTool("self.servoclock.SetDonotDisturbTimePeriod", "设置机械时钟勿扰时间段,比如22:00到7:00", PropertyList({
        Property("startTime", kPropertyTypeString),
        Property("endTime", kPropertyTypeString)
    }), [this](const PropertyList& properties) -> ReturnValue {
        tm start = StringToTm(properties["startTime"].value<std::string>());
        tm end = StringToTm(properties["endTime"].value<std::string>());
        ESP_LOGI(TAG, "勿扰时段: %02d:%02d至%02d:%02d",
                start.tm_hour, start.tm_min, end.tm_hour, end.tm_min);
        SetDonotDisturbTimePeriod(start, end);
        return true;
    });

    mcp_server.AddTool("self.servoclock.setMaintenanceMode", "设置机械时钟进入维修模式,true:进入维修模式;false:退出维修模式", PropertyList({
        Property("repair", kPropertyTypeBoolean)
    }), [this](const PropertyList& properties) -> ReturnValue {
        bool data = properties["repair"].value<bool>();
        ESP_LOGI(TAG, "设定维修模式: %d", data);
        setMaintenanceMode(data);
        return true;
    });

    mcp_server.AddTool("self.servoclock.reboot", "重新启动机械时钟", PropertyList(), [this](const PropertyList&) -> ReturnValue {
        esp_restart();
        return true;
    });
}


ServoClockManager::~ServoClockManager()
{
    if (clock_timer_handle_ != nullptr) {
        esp_timer_stop(clock_timer_handle_);
        esp_timer_delete(clock_timer_handle_);
    }
}

void ServoClockManager::SetDisplayMode(int mode)
{
    m_dispmode = mode;

    // 倒计时功能就打断应答
    if (5 == mode) {
        vTaskDelay(pdMS_TO_TICKS(2000)); // 2000 ms
        auto& app = Application::GetInstance();
        app.AbortSpeaking(kAbortReasonNone);
    }
}

// 依据显示模式操作舵机机械时钟
// 0:显示时间;1:显示年份;2:显示日期;3:显示秒针;4:显示笑脸
void ServoClockManager::OnServoClockTimer()
{
    ESP_LOGI(TAG, "DisplayClock mode=%d", m_dispmode);
    ESP_LOGI(TAG, "已设定勿扰时间%d:%d ~ %d:%d",
        m_sDonotDisturbTimePeriodStart.tm_hour,
        m_sDonotDisturbTimePeriodStart.tm_min,
        m_sDonotDisturbTimePeriodEnd.tm_hour,
        m_sDonotDisturbTimePeriodEnd.tm_min);
    time_t current_time;
    time(&current_time); // 获取当前时间
    struct tm *local_time = localtime(&current_time); // 转换为本地时间
    ESP_LOGI(TAG,"Current Year: %d, Month: %d, Day: %d, Hour: %d, Minute: %d, Second: %d\n",
           local_time->tm_year + 1900, local_time->tm_mon + 1, local_time->tm_mday,
           local_time->tm_hour, local_time->tm_min, local_time->tm_sec);

    switch (m_dispmode) {
        case 0:
        {
            DispTime(local_time);
            break;
        }
        case 1:
        {
            DispYear(local_time);
            break;
        }
        case 2:
        {
            DispDate(local_time);
            break;
        }
        case 3:
        {
            DispSeconds(local_time);
            break;
        }
        case 4:
        {
            DispEmote();
            break;
        }
        case 5: // 倒计时
        {
            DispCountdown();
            break;
        }
        case 6: // 计算结果
        {
            break;
        }
        case 7: // 显示当前温度
        {
            DispCurrentTemp();
            break;
        }
        case 8: // 显示当前湿度
        {
            DispCurreHntHumidity();
            break;
        }
        case 9: //
        {
            break;
        }
        default:
            DispTime(local_time);
            break;
    }

}

// 舵机控制函数
// 参数1为舵机序号；
// 参数2为控制值（0或1）
void ServoClockManager::ControlServo(uint8_t x, uint8_t y)
{
    uint8_t z = 0;
    // 如果舵机序号大于16，则发送给2号驱动板
    if (x >= 16) {
        x -= 16;
        z = 1;
    }
    else{
        z = 0;
    }

    uint8_t motor_ctrl[5] = {(uint8_t)(0x06 + 4 * x), 0x00, 0x00, 0x80, 0x00};
#if 0
    if (0 == y){
        ;
    }
    else{
        motor_ctrl[3] = 0x70;
        motor_ctrl[4] = 0x01;
    }
#else
    uint8_t angle = ANGLE_90;
    if (0 == y){
        ;
    }
    else {
        angle = ANGLE_180;
    }
    uint16_t pulse = angle * (512 - 102) / 180 + 102;
    motor_ctrl[3] = (uint8_t)(pulse & 0xFF);
    motor_ctrl[4] =(uint8_t)((pulse >> 8) & 0x0F);
#endif

    if (1 == z) {
        memcpy(m_motor_ctrl_board_2[x], motor_ctrl, 5);
    }
    else {
        memcpy(m_motor_ctrl_board_1[x], motor_ctrl, 5);
    }

}

// 机械时钟两个数字显示控制
// digit[4][7]指机械时钟圆点前后两个两位数字
// dot1，2指机械时钟的上下两个圆点,0关闭，1打开
void ServoClockManager::ControlDispClockDigit(uint8_t digit[][7], uint8_t dot1, uint8_t dot2)
{
    // 初始化buffer数组
    memset(m_motor_ctrl_board_1, 0, sizeof(m_motor_ctrl_board_1));
    memset(m_motor_ctrl_board_2, 0, sizeof(m_motor_ctrl_board_2));

    // 轮询4个数字显示控制
    for (uint8_t ctrl_idx1 = 0; ctrl_idx1 < 4; ctrl_idx1++) {
        // 控制显示一个数字
        for (uint8_t ctrl_idx2 = 0; ctrl_idx2 < 7; ctrl_idx2++) {
            if (digit[ctrl_idx1][ctrl_idx2] == 0){
                ControlServo(ctrl_idx1 * 8 + ctrl_idx2, 0);
            }
            else {
                ControlServo(ctrl_idx1 * 8 + ctrl_idx2, 1);
            }
        }
    }

    // 显示时间时，两个小圆点默认on
    ControlServo(7, dot1);
    //vTaskDelay(pdMS_TO_TICKS(30)); // 30ms

    // 显示时间时，两个小圆点默认on
    ControlServo(23, dot2);

    // 多发数据到舵机控制板
    //ESP_LOGI(TAG, "ServoClockManager 多发数据到舵机控制板 start");
    bool need_send_flg = false;
    for (uint8_t i = 0; i < 15; i++) {
        for (uint8_t j = 1; j < 5; j++) {
            if (m_motor_ctrl_board_1[i][j] != m_motor_ctrl_board_1_old[i][j]) {
                need_send_flg = true;
                break;
            }
        }
        if (true == need_send_flg) {
            uint8_t motor_ctrl_data[5] = {0};
            memcpy(motor_ctrl_data,  m_motor_ctrl_board_1[i], 5);
            auto& board = Board::GetInstance();
            board.setDataToPCA9685(SERVO_CLOCK_ADDR_0X40, motor_ctrl_data, 5);
            need_send_flg = false;
        }
        memcpy(m_motor_ctrl_board_1_old[i], m_motor_ctrl_board_1[i], 5);
    }

    need_send_flg = false;
    for (uint8_t i = 0; i < 15; i++) {
        // printf("m_motor_ctrl_board_2[%d]0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n",
        //     i,
        //     m_motor_ctrl_board_2[i][0],
        //     m_motor_ctrl_board_2[i][1],
        //     m_motor_ctrl_board_2[i][2],
        //     m_motor_ctrl_board_2[i][3],
        //     m_motor_ctrl_board_2[i][4]);

        //     printf("m_motor_ctrl_board_2_old[%d]0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n",
        //         i,
        //         m_motor_ctrl_board_2_old[i][0],
        //         m_motor_ctrl_board_2_old[i][1],
        //         m_motor_ctrl_board_2_old[i][2],
        //         m_motor_ctrl_board_2_old[i][3],
        //         m_motor_ctrl_board_2_old[i][4]);
        for (uint8_t j = 1; j < 5; j++) {
            if (m_motor_ctrl_board_2[i][j] != m_motor_ctrl_board_2_old[i][j]) {
                need_send_flg = true;
                break;
            }
        }

        if (true == need_send_flg) {
            uint8_t motor_ctrl_data[5] = {0};
            memcpy(motor_ctrl_data,  m_motor_ctrl_board_2[i], 5);
            // printf("motor_ctrl_data[%d]0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n",
            //     i,
            //     motor_ctrl_data[0],
            //     motor_ctrl_data[1],
            //     motor_ctrl_data[2],
            //     motor_ctrl_data[3],
            //     motor_ctrl_data[4]);
            auto& board = Board::GetInstance();
            board.setDataToPCA9685(SERVO_CLOCK_ADDR_0X41, motor_ctrl_data, 5);
            need_send_flg = false;
        }
        memcpy(m_motor_ctrl_board_2_old[i], m_motor_ctrl_board_2[i], 5);
    }
    // ESP_LOGI(TAG, "ServoClockManager 多发数据到舵机控制板 end");
}

// 显示时间
void ServoClockManager::DispTime(tm *local_time)
{
    m_dispYearFlg = false;
    m_dispDateFlg = false;
    m_dispEmoteFlg = false;

    // 设置勿扰时间段（比如：22:00-7:00）
    bool inDND = false;
    if (local_time->tm_hour > m_sDonotDisturbTimePeriodStart.tm_hour || local_time->tm_hour < m_sDonotDisturbTimePeriodEnd.tm_hour) {
        inDND = true;
    } else if (local_time->tm_hour == m_sDonotDisturbTimePeriodStart.tm_hour && local_time->tm_min >= m_sDonotDisturbTimePeriodStart.tm_min) {
        inDND = true;
    } else if (local_time->tm_hour == m_sDonotDisturbTimePeriodEnd.tm_hour && local_time->tm_min <= m_sDonotDisturbTimePeriodEnd.tm_min) {
        inDND = true;
    }

    if(inDND) {
        ESP_LOGI(TAG, "当前进入勿扰时间阶段");
        ControlDispClockDigit(display_digits_dnd, 1, 1);
    } else {
        uint8_t display_list[4] = { 0 };
        display_list[0] = local_time->tm_hour / 10;
        display_list[0] = display_list[0] % 10;
        display_list[1] = local_time->tm_hour % 10;

        display_list[2] = local_time->tm_min / 10;
        display_list[2] = display_list[2] % 10;
        display_list[3] = local_time->tm_min % 10;

        uint8_t digit[4][7] = { 0 };
        for (uint8_t ctrl_idx1 = 0; ctrl_idx1 < 4; ctrl_idx1++) {
            memcpy(digit[ctrl_idx1], display_digits[display_list[ctrl_idx1]], 7);
        }
        ESP_LOGI(TAG, "当前在显示时间");
        ControlDispClockDigit(digit, 1, 1);
    }

    m_dispTimeFlg = true;
}

// 显示年份
void ServoClockManager::DispYear(tm *local_time)
{
    m_dispDateFlg = false;
    m_dispEmoteFlg = false;
    m_dispTimeFlg = false;
    if (true == m_dispYearFlg) {
        ESP_LOGI(TAG, "机械时钟中年份已经显示，无需连续触发");
        return;
    }

    int year = local_time->tm_year + 1900;

    uint8_t word1 = year / 100;
    uint8_t word2 = year % 100;
    uint8_t display_list[4] = { 0 };
    display_list[0] = word1 / 10;
    display_list[0] = display_list[0] % 10;
    display_list[1] = word1 % 10;

    display_list[2] = word2 / 10;
    display_list[2] = display_list[2] % 10;
    display_list[3] = word2 % 10;

    uint8_t digit[4][7] = { 0 };
    for (uint8_t ctrl_idx1 = 0; ctrl_idx1 < 4; ctrl_idx1++) {
        memcpy(digit[ctrl_idx1], display_digits[display_list[ctrl_idx1]], 7);
    }
    ControlDispClockDigit(digit, 0, 0);

    // flag 置为 true
    m_dispYearFlg = true;
}

// 显示日期
void ServoClockManager::DispDate(tm *local_time)
{
    m_dispYearFlg = false;
    m_dispEmoteFlg = false;
    m_dispTimeFlg = false;
    if (true == m_dispDateFlg) {
        ESP_LOGI(TAG, "机械时钟中日期已经显示，无需连续触发");
        return;
    }

    // 先显示年份，再显示日期
    int year = local_time->tm_year + 1900;

    uint8_t word1 = year / 100;
    uint8_t word2 = year % 100;
    uint8_t display_list[4] = { 0 };
    display_list[0] = word1 / 10;
    display_list[0] = display_list[0] % 10;
    display_list[1] = word1 % 10;

    display_list[2] = word2 / 10;
    display_list[2] = display_list[2] % 10;
    display_list[3] = word2 % 10;

    uint8_t digit[4][7] = { 0 };
    for (uint8_t ctrl_idx1 = 0; ctrl_idx1 < 4; ctrl_idx1++) {
        memcpy(digit[ctrl_idx1], display_digits[display_list[ctrl_idx1]], 7);
    }
    ControlDispClockDigit(digit, 0, 0);

    // 暂停timer
    if (clock_timer_handle_ != nullptr) {
        esp_timer_stop(clock_timer_handle_);
    }

    vTaskDelay(pdMS_TO_TICKS(3 * 1000)); // 30ms
    // 显示日期
    display_list[0] = (local_time->tm_mon + 1) / 10;
    display_list[0] = display_list[0] % 10;
    display_list[1] = (local_time->tm_mon + 1) % 10;

    display_list[2] = local_time->tm_mday / 10;
    display_list[2] = display_list[2] % 10;
    display_list[3] = local_time->tm_mday % 10;

    for (uint8_t ctrl_idx1 = 0; ctrl_idx1 < 4; ctrl_idx1++) {
        memcpy(digit[ctrl_idx1], display_digits[display_list[ctrl_idx1]], 7);
    }

    ControlDispClockDigit(digit, 0, 1);

    // if (clock_timer_handle_ != nullptr) {
    //     ESP_ERROR_CHECK(esp_timer_start_periodic(clock_timer_handle_, 1000000));
    //     auto& board = Board::GetInstance();
    //     board.initPCA9685();
    // }

    // flag 置为 true
    m_dispDateFlg = true;
}

// 显示秒针
void ServoClockManager::DispSeconds(tm *local_time)
{
    m_dispYearFlg = false;
    m_dispDateFlg = false;
    m_dispEmoteFlg = false;
    m_dispTimeFlg = false;
    uint8_t display_list[4] = { 0 };
    display_list[0] = local_time->tm_min / 10;
    display_list[0] = display_list[0] % 10;
    display_list[1] = local_time->tm_min % 10;

    display_list[2] = local_time->tm_sec / 10;
    display_list[2] = display_list[2] % 10;
    display_list[3] = local_time->tm_sec % 10;

    uint8_t digit[4][7] = { 0 };
    for (uint8_t ctrl_idx1 = 0; ctrl_idx1 < 4; ctrl_idx1++) {
        memcpy(digit[ctrl_idx1], display_digits[display_list[ctrl_idx1]], 7);
    }

    ControlDispClockDigit(digit, 1, 1);
}

// 显示表情
void ServoClockManager::DispEmote()
{
    m_dispYearFlg = false;
    m_dispDateFlg = false;
    m_dispTimeFlg = false;

    if (true == m_dispEmoteFlg) {
        return;
    }

    ControlDispClockDigit(display_digits_smile, 0, 1);

    // flag 置为 true
    m_dispEmoteFlg = true;
}

// 显示倒计时
void ServoClockManager::DispCountdown()
{
    if (m_CountdownTotalSeconds < 0) {
        // 恢复显示时间
        m_dispmode = 0;
        return;
    }
    m_dispYearFlg = false;
    m_dispDateFlg = false;
    m_dispEmoteFlg = false;
    m_dispTimeFlg = false;


    uint8_t tm_min = m_CountdownTotalSeconds / 60;
    uint8_t tm_sec = m_CountdownTotalSeconds % 60;

    std::string str = std::to_string(tm_min) + ":" + std::to_string(tm_sec);
    auto& app = Application::GetInstance();
    app.DispSpecialText(str);

    uint8_t display_list[4] = { 0 };
    display_list[0] = tm_min / 10;
    display_list[0] = display_list[0] % 10;
    display_list[1] = tm_min % 10;

    display_list[2] = tm_sec / 10;
    display_list[2] = display_list[2] % 10;
    display_list[3] = tm_sec % 10;

    uint8_t digit[4][7] = { 0 };
    for (uint8_t ctrl_idx1 = 0; ctrl_idx1 < 4; ctrl_idx1++) {
        memcpy(digit[ctrl_idx1], display_digits[display_list[ctrl_idx1]], 7);
    }

    ControlDispClockDigit(digit, 1, 1);
    m_CountdownTotalSeconds -= 1;
}

// 显示计算结果
void ServoClockManager::SetCalculationResult(uint16_t data)
{
    m_dispYearFlg = false;
    m_dispDateFlg = false;
    m_dispEmoteFlg = false;
    m_dispTimeFlg = false;

    uint8_t word1 = data / 100;
    uint8_t word2 = data % 100;
    uint8_t display_list[4] = { 0 };
    display_list[0] = word1 / 10;
    display_list[0] = display_list[0] % 10;
    display_list[1] = word1 % 10;

    display_list[2] = word2 / 10;
    display_list[2] = display_list[2] % 10;
    display_list[3] = word2 % 10;

    uint8_t digit[4][7] = { 0 };
    for (uint8_t ctrl_idx1 = 0; ctrl_idx1 < 4; ctrl_idx1++) {
        memcpy(digit[ctrl_idx1], display_digits[display_list[ctrl_idx1]], 7);
    }

    ControlDispClockDigit(digit, 0, 0);
}

// 显示当前温度
void ServoClockManager::DispCurrentTemp()
{
    auto& app = Application::GetInstance();
    if(app.humiture_m_ == nullptr){
        return;
    }
    uint8_t data = (uint8_t)(app.humiture_m_->GetCurrentTemperatureData());
    ESP_LOGI(TAG, "当前温度 %d", data);

    uint8_t display_list[4] = { 0 };
    display_list[0] = data / 10;
    display_list[0] = display_list[0] % 10;
    display_list[1] = data % 10;

    uint8_t digit[4][7] = { 0 };
    // 前两位数字
    for (uint8_t ctrl_idx1 = 0; ctrl_idx1 < 2; ctrl_idx1++) {
        memcpy(digit[ctrl_idx1], display_digits[display_list[ctrl_idx1]], 7);
    }

    // 摄氏度单位
    for (uint8_t ctrl_idx1 = 2; ctrl_idx1 < 4; ctrl_idx1++) {
        memcpy(digit[ctrl_idx1], display_digits_degree[ctrl_idx1], 7);
    }

    ControlDispClockDigit(digit, 0, 0);
}

// 显示当前湿度
void ServoClockManager::DispCurreHntHumidity()
{
    auto& app = Application::GetInstance();
    if(app.humiture_m_ == nullptr){
        return;
    }
    uint8_t data = (uint8_t)(app.humiture_m_->GetCurrenthumidityData());
    ESP_LOGI(TAG, "当前湿度 %d", data);

    uint8_t display_list[4] = { 0 };
    display_list[0] = data / 10;
    display_list[0] = display_list[0] % 10;
    display_list[1] = data % 10;

    uint8_t digit[4][7] = { 0 };
    // 前两位数字
    for (uint8_t ctrl_idx1 = 0; ctrl_idx1 < 2; ctrl_idx1++) {
        memcpy(digit[ctrl_idx1], display_digits[display_list[ctrl_idx1]], 7);
    }

    // 摄氏度单位
    for (uint8_t ctrl_idx1 = 2; ctrl_idx1 < 4; ctrl_idx1++) {
        memcpy(digit[ctrl_idx1], display_digits_persent[ctrl_idx1], 7);
    }

    ControlDispClockDigit(digit, 0, 0);
}

// 维修模式
void ServoClockManager::setMaintenanceMode(bool status)
{
    auto& board = Board::GetInstance();
    if (true == status) {
        // 暂停timer
        if (clock_timer_handle_ != nullptr) {
            esp_timer_stop(clock_timer_handle_);
        }
        for (uint8_t x = 0; x < 16; x++) {
            uint8_t motor_ctrl[5] = {(uint8_t)(0x06 + 4 * x), 0x00, 0x00, 0x80, 0x00};
            uint16_t pulse = ANGLE_180 * (512 - 102) / 180 + 102;
            motor_ctrl[3] = (uint8_t)(pulse & 0xFF);
            motor_ctrl[4] =(uint8_t)((pulse >> 8) & 0x0F);

            board.setDataToPCA9685(SERVO_CLOCK_ADDR_0X40, motor_ctrl, 5);
            board.setDataToPCA9685(SERVO_CLOCK_ADDR_0X41, motor_ctrl, 5);
        }
        std::string str = "请在1分钟内完成检查";
        auto& app = Application::GetInstance();
        app.DispSpecialText(str);
        vTaskDelay(60*1000 / portTICK_PERIOD_MS);

        for (uint8_t x = 0; x < 16; x++) {
            uint8_t motor_ctrl[5] = {(uint8_t)(0x06 + 4 * x), 0x00, 0x00, 0x80, 0x00};
            uint16_t pulse = ANGLE_90 * (512 - 102) / 180 + 102;
            motor_ctrl[3] = (uint8_t)(pulse & 0xFF);
            motor_ctrl[4] =(uint8_t)((pulse >> 8) & 0x0F);

            board.setDataToPCA9685(SERVO_CLOCK_ADDR_0X40, motor_ctrl, 5);
            board.setDataToPCA9685(SERVO_CLOCK_ADDR_0X41, motor_ctrl, 5);
        }
    }
    else {
        if (clock_timer_handle_ != nullptr) {
            ESP_ERROR_CHECK(esp_timer_start_periodic(clock_timer_handle_, 1000000));
        }
    }
}